home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Peter's Final Project / src / world.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  17.8 KB  |  733 lines  |  [TEXT/KAHL]

  1. /*
  2.  *  Peter's Final Project -- A texture mapping demonstration
  3.  *  © 1995, Peter Mattis
  4.  *
  5.  *  E-mail:
  6.  *  petm@soda.csua.berkeley.edu
  7.  *
  8.  *  Snail-mail:
  9.  *   Peter Mattis
  10.  *   557 Fort Laramie Dr.
  11.  *   Sunnyvale, CA 94087
  12.  *
  13.  *  Avaible from:
  14.  *  http://www.csua.berkeley.edu/~petm/final.html
  15.  *
  16.  *  This program is free software; you can redistribute it and/or modify
  17.  *  it under the terms of the GNU General Public License as published by
  18.  *  the Free Software Foundation; either version 2 of the License, or
  19.  *  (at your option) any later version.
  20.  *
  21.  *  This program is distributed in the hope that it will be useful,
  22.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  23.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24.  *  GNU General Public License for more details.
  25.  *
  26.  *  You should have received a copy of the GNU General Public License
  27.  *  along with this program; if not, write to the Free Software
  28.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29.  */
  30.  
  31. #include <assert.h>
  32. #include <stdio.h>
  33.  
  34. #include "face.h"
  35. #include "list.h"
  36. #include "maze.h"
  37. #include "object.h"
  38. #include "sector.h"
  39. #include "sys.stuff.h"
  40. #include "texture.h"
  41. #include "world.h"
  42.  
  43. /*
  44.  * This define affect the size (width) of a sector.
  45.  */
  46.  
  47. #define CELL_SIZE NUM_ONE * 2
  48.  
  49. /*
  50.  * Declare the functions private to this module.
  51.  */
  52.  
  53. void world_make_points (void);
  54. SECTOR world_make_sector (short, short);
  55. FACE world_make_floor_face (short, short);
  56. FACE world_make_ceiling_face (short, short);
  57. FACE world_make_west_face (short, short);
  58. FACE world_make_east_face (short, short);
  59. FACE world_make_north_face (short, short);
  60. FACE world_make_south_face (short, short);
  61.  
  62. /*
  63.  * These global variables are used instead of passing
  64.  *  lots of parameters around in function calls.
  65.  */
  66.  
  67. static WORLD cur_world;
  68. static MAZE cur_maze;
  69.  
  70. /*
  71.  * The offset into the points array where the normals begin.
  72.  */
  73.  
  74. static long normal_offset;
  75.  
  76. /*
  77.  * The textures to use for the floor, ceiling, and walls respectively.
  78.  */
  79.  
  80. static TEXTURE floor_texture;
  81. static TEXTURE ceiling_texture;
  82. static TEXTURE wall_texture;
  83.  
  84. /*
  85.  * Allocate a world.
  86.  */
  87.  
  88. WORLD
  89. make_world ()
  90. {
  91.     WORLD world;
  92.  
  93.     world = (WORLD) ALLOC (sizeof (_WORLD));
  94.  
  95.     set_world_points (world, NULL);
  96.     set_world_faces (world, NULL);
  97.  
  98.     return world;
  99. }
  100.  
  101. /*
  102.  * Free a world.
  103.  */
  104.  
  105. void
  106. free_world (w)
  107.     WORLD w;
  108. {
  109.     FREE (w);
  110. }
  111.  
  112. /*
  113.  * Initialize a world from a maze.
  114.  */
  115.  
  116. void
  117. world_from_maze (w, m, wtn, ftn, ctn)
  118.     WORLD w;
  119.     MAZE m;
  120.     char *wtn, *ftn, *ctn;
  121. {
  122.     long n_points;
  123.     short i, j;
  124.     SECTOR s;
  125.  
  126.     /*
  127.      * Set up some global variables so we don't have to
  128.      *  pass them around to every function.
  129.      */
  130.     cur_world = w;
  131.     cur_maze = m;
  132.  
  133.     /*
  134.      * Calculate the number of points needed for the world.
  135.      * "2 * (maze_size(cur_maze) - 1) * (maze_size(cur_maze) - 1)"
  136.      *  is the number of points needed to define the every possible
  137.      *  face in the maze.
  138.      * And, of course, we need 6 extra points for normal vectors.
  139.      *  (It's a simple maze, there are only 6 possible face orientations).
  140.      */
  141.     n_points = (2 * (maze_size (cur_maze) - 1) * (maze_size (cur_maze) - 1) + 6);
  142.  
  143.     /*
  144.      * Allocate the points.
  145.      */
  146.     world_points (cur_world) = (POINT) ALLOC (sizeof (_POINT) * n_points);
  147.     assert (world_points (cur_world) != NULL);
  148.  
  149.     /*
  150.      * Initialize the points.
  151.      */
  152.     world_make_points ();
  153.  
  154.     /*
  155.      * Create some textures.
  156.      */
  157.     wall_texture = make_texture ();
  158.     floor_texture = make_texture ();
  159.     ceiling_texture = make_texture ();
  160.  
  161.     /*
  162.      * Read in the wall texture.
  163.      */
  164.     if (wtn)
  165.         texture_read (wall_texture, wtn);
  166.     else
  167.         texture_read (wall_texture, ":textures:marble_wall.jpg");
  168.  
  169.     /*
  170.      * Read in the floor texture.
  171.      */
  172.     if (ftn)
  173.         texture_read (floor_texture, ftn);
  174.     else
  175.         texture_read (floor_texture, ":textures:marble_floor.jpg");
  176.  
  177.     /*
  178.      * Read in the ceiling texture.
  179.      */
  180.     if (ctn)
  181.         texture_read (ceiling_texture, ctn);
  182.     else
  183.         texture_read (ceiling_texture, ":textures:marble_floor.jpg");
  184.  
  185.     /*
  186.      * Allocate and initialize all the sectors in this world.
  187.      * Initialization involves creating the faces.
  188.      */
  189.     for (i = 0; i < maze_size (cur_maze); i++)
  190.         for (j = 0; j < maze_size (cur_maze); j++)
  191.         {
  192.             if (!maze_element_state (cur_maze, i, j))
  193.             {
  194.                 set_maze_element_sector (cur_maze, i, j, make_sector ());
  195.                 world_make_sector (i - 1, j - 1);
  196.             }
  197.             else
  198.             {
  199.                 set_maze_element_sector (cur_maze, i, j, NULL);
  200.             }
  201.         }
  202.  
  203.     /*
  204.      * Once all the sectors have been created, all we need
  205.      *  to do is link them together. The result is one large
  206.      *  graph. (Or small, depends on how big the maze is).
  207.      * Links are only made to the neighbors in the 4 cardinal.
  208.      */
  209.     for (i = 0; i < maze_size (cur_maze); i++)
  210.     {
  211.         for (j = 0; j < maze_size (cur_maze); j++)
  212.         {
  213.             s = maze_element_sector (cur_maze, i, j);
  214.             if (s)
  215.             {
  216.                 if (maze_element_sector (cur_maze, i, j - 1))
  217.                     sector_neighbors (s) = sectors_add_sector (sector_neighbors (s),
  218.                     maze_element_sector (cur_maze, i, j - 1));
  219.                 if (maze_element_sector (cur_maze, i + 1, j))
  220.                     sector_neighbors (s) = sectors_add_sector (sector_neighbors (s),
  221.                     maze_element_sector (cur_maze, i + 1, j));
  222.                 if (maze_element_sector (cur_maze, i, j + 1))
  223.                     sector_neighbors (s) = sectors_add_sector (sector_neighbors (s),
  224.                     maze_element_sector (cur_maze, i, j + 1));
  225.                 if (maze_element_sector (cur_maze, i - 1, j))
  226.                     sector_neighbors (s) = sectors_add_sector (sector_neighbors (s),
  227.                     maze_element_sector (cur_maze, i - 1, j));
  228.             }
  229.         }
  230.     }
  231. }
  232.  
  233. /*
  234.  * Initialize the points for the current world.
  235.  */
  236.  
  237. void
  238. world_make_points ()
  239. {
  240.     short i, j, n;
  241.     POINT p;
  242.  
  243.     /*
  244.      * Initialize the floor points.
  245.      */
  246.     n = 0;
  247.     for (i = 0; i < (maze_size (cur_maze) - 1); i++)
  248.     {
  249.         for (j = 0; j < (maze_size (cur_maze) - 1); j++)
  250.         {
  251.             p = &world_point (cur_world, n++);
  252.  
  253.             set_point_x (p, j * CELL_SIZE);
  254.             set_point_y (p, NUM_ZERO);
  255.             set_point_z (p, i * CELL_SIZE);
  256.             set_point_w (p, NUM_ONE);
  257.         }
  258.     }
  259.  
  260.     /*
  261.      * Initialize the ceiling points. (This is the same
  262.      *  as above except the y coordinate is set to 1).
  263.      */
  264.     for (i = 0; i < (maze_size (cur_maze) - 1); i++)
  265.     {
  266.         for (j = 0; j < (maze_size (cur_maze) - 1); j++)
  267.         {
  268.             p = &world_point (cur_world, n++);
  269.  
  270.             set_point_x (p, j * CELL_SIZE);
  271.             set_point_y (p, CELL_SIZE);
  272.             set_point_z (p, i * CELL_SIZE);
  273.             set_point_w (p, NUM_ONE);
  274.         }
  275.     }
  276.  
  277.     /*
  278.      * Remember the normal offset.
  279.      */
  280.     normal_offset = n;
  281.  
  282.     /*
  283.      * Initialize the normals. We need a normal in the
  284.      *  both the positive and negative direction of x, y
  285.      *  and z;
  286.      */
  287.     
  288.     p = &world_point (cur_world, n++);
  289.     set_point_x (p, NUM_ZERO);
  290.     set_point_y (p, NUM_ONE);
  291.     set_point_z (p, NUM_ZERO);
  292.     set_point_w (p, NUM_ZERO);
  293.  
  294.     p = &world_point (cur_world, n++);
  295.     set_point_x (p, NUM_ZERO);
  296.     set_point_y (p, -NUM_ONE);
  297.     set_point_z (p, NUM_ZERO);
  298.     set_point_w (p, NUM_ZERO);
  299.  
  300.     p = &world_point (cur_world, n++);
  301.     set_point_x (p, NUM_ONE);
  302.     set_point_y (p, NUM_ZERO);
  303.     set_point_z (p, NUM_ZERO);
  304.     set_point_w (p, NUM_ZERO);
  305.  
  306.     p = &world_point (cur_world, n++);
  307.     set_point_x (p, -NUM_ONE);
  308.     set_point_y (p, NUM_ZERO);
  309.     set_point_z (p, NUM_ZERO);
  310.     set_point_w (p, NUM_ZERO);
  311.  
  312.     p = &world_point (cur_world, n++);
  313.     set_point_x (p, NUM_ZERO);
  314.     set_point_y (p, NUM_ZERO);
  315.     set_point_z (p, NUM_ONE);
  316.     set_point_w (p, NUM_ZERO);
  317.  
  318.     p = &world_point (cur_world, n++);
  319.     set_point_x (p, NUM_ZERO);
  320.     set_point_y (p, NUM_ZERO);
  321.     set_point_z (p, -NUM_ONE);
  322.     set_point_w (p, NUM_ZERO);
  323. }
  324.  
  325. /*
  326.  * Create a sector for the current world.
  327.  */
  328.  
  329. SECTOR
  330. world_make_sector (i, j)
  331.     short i, j;
  332. {
  333.     SECTOR sector;
  334.     FACE face;
  335.  
  336.     /*
  337.      * Grab the sector for this cell from the maze.
  338.      */
  339.     sector = maze_element_sector (cur_maze, i + 1, j + 1);
  340.  
  341.     /*
  342.      * Create the various faces and add them to this
  343.      *  sectors list.
  344.      */
  345.     
  346.     face = world_make_floor_face (i, j);
  347.     if (face)
  348.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  349.  
  350.     face = world_make_ceiling_face (i, j);
  351.     if (face)
  352.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  353.  
  354.     face = world_make_west_face (i, j);
  355.     if (face)
  356.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  357.  
  358.     face = world_make_east_face (i, j);
  359.     if (face)
  360.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  361.  
  362.     face = world_make_north_face (i, j);
  363.     if (face)
  364.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  365.  
  366.     face = world_make_south_face (i, j);
  367.     if (face)
  368.         set_sector_faces (sector, faces_add_face (sector_faces (sector), face));
  369.  
  370.     return sector;
  371. }
  372.  
  373. /*
  374.  * Create a floor face.
  375.  */
  376.  
  377. FACE
  378. world_make_floor_face (i, j)
  379.     short i, j;
  380. {
  381.     FACE face;
  382.     short temp;
  383.     short size;
  384.  
  385.     size = maze_size (cur_maze) - 1;
  386.  
  387.     face = make_face ();
  388.     set_face_normal (face, &world_point (cur_world, normal_offset + 1));
  389.     set_face_texture (face, floor_texture);
  390.     set_face_obstructs (face, TRUE);
  391.  
  392.     temp = i * size + j + (size * size);
  393.     face_points (face) = points_add_point (face_points (face),
  394.         &world_point (cur_world, temp));
  395.     face_points (face) = points_add_point (face_points (face),
  396.         &world_point (cur_world, temp + 1));
  397.     face_points (face) = points_add_point (face_points (face),
  398.         &world_point (cur_world, temp + 1 + size));
  399.     face_points (face) = points_add_point (face_points (face),
  400.         &world_point (cur_world, temp + size));
  401.  
  402.     set_face_texture_o (face, &world_point (cur_world, temp));
  403.     set_face_texture_u (face, &world_point (cur_world, temp + 1));
  404.     set_face_texture_v (face, &world_point (cur_world, temp + size));
  405.  
  406.     return face;
  407. }
  408.  
  409. /*
  410.  * Create a ceiling face.
  411.  */
  412.  
  413. FACE
  414. world_make_ceiling_face (i, j)
  415.     short i, j;
  416. {
  417.     FACE face;
  418.     short temp;
  419.     short size;
  420.  
  421.     size = maze_size (cur_maze) - 1;
  422.  
  423.     face = make_face ();
  424.     set_face_normal (face, &world_point (cur_world, normal_offset + 0));
  425.     set_face_texture (face, ceiling_texture);
  426.     set_face_obstructs (face, TRUE);
  427.  
  428.     temp = i * size + j;
  429.  
  430.     face_points (face) = points_add_point (face_points (face),
  431.         &world_point (cur_world, temp));
  432.     face_points (face) = points_add_point (face_points (face),
  433.         &world_point (cur_world, temp + 1));
  434.     face_points (face) = points_add_point (face_points (face),
  435.         &world_point (cur_world, temp + 1 + size));
  436.     face_points (face) = points_add_point (face_points (face),
  437.         &world_point (cur_world, temp + size));
  438.  
  439.     set_face_texture_o (face, &world_point (cur_world, temp));
  440.     set_face_texture_u (face, &world_point (cur_world, temp + 1));
  441.     set_face_texture_v (face, &world_point (cur_world, temp + size));
  442.  
  443.     return face;
  444. }
  445.  
  446. /*
  447.  * Create a west face.
  448.  */
  449.  
  450. FACE
  451. world_make_west_face (i, j)
  452.     short i, j;
  453. {
  454.     FACE face;
  455.     short temp;
  456.     short size;
  457.     short offset;
  458.  
  459.     if (maze_element_state (cur_maze, i + 1, j))
  460.     {
  461.         /*
  462.          * There is a wall next to us, so make a "real" face.
  463.          */
  464.         
  465.         size = maze_size (cur_maze) - 1;
  466.         offset = size * size;
  467.  
  468.         face = make_face ();
  469.         set_face_normal (face, &world_point (cur_world, normal_offset + 2));
  470.         set_face_texture (face, wall_texture);
  471.         set_face_obstructs (face, TRUE);
  472.  
  473.         temp = i * size + j;
  474.         face_points (face) = points_add_point (face_points (face),
  475.             &world_point (cur_world, temp));
  476.         face_points (face) = points_add_point (face_points (face),
  477.             &world_point (cur_world, temp + size));
  478.         face_points (face) = points_add_point (face_points (face),
  479.             &world_point (cur_world, temp + size + offset));
  480.         face_points (face) = points_add_point (face_points (face),
  481.             &world_point (cur_world, temp + offset));
  482.  
  483.         set_face_texture_o (face, &world_point (cur_world, temp + size));
  484.         set_face_texture_u (face, &world_point (cur_world, temp));
  485.         set_face_texture_v (face, &world_point (cur_world, temp + size + offset));
  486.  
  487.         return face;
  488.     }
  489.     else
  490.     {
  491.         /*
  492.          * There is nothing next to us, so make a "fake" face.
  493.          * (That is, it won't be visible and won't obstruct movement).
  494.          */
  495.         
  496.         face = make_face ();
  497.         set_face_normal (face, &world_point (cur_world, normal_offset + 2));
  498.         set_face_texture (face, wall_texture);
  499.         set_face_obstructs (face, FALSE);
  500.  
  501.         size = maze_size (cur_maze) - 1;
  502.         temp = i * size + j;
  503.         face_points (face) = points_add_point (face_points (face),
  504.             &world_point (cur_world, temp));
  505.         face_points (face) = points_add_point (face_points (face),
  506.             &world_point (cur_world, temp + size));
  507.  
  508.         set_face_texture_o (face, &world_point (cur_world, temp + size));
  509.         set_face_texture_u (face, &world_point (cur_world, temp));
  510.         set_face_texture_v (face, &world_point (cur_world, temp + size + offset));
  511.  
  512.         return face;
  513.     }
  514.  
  515.     return NULL;
  516. }
  517.  
  518. /*
  519.  * Create an east face.
  520.  */
  521.  
  522. FACE
  523. world_make_east_face (i, j)
  524.     short i, j;
  525. {
  526.     FACE face;
  527.     short temp;
  528.     short size;
  529.     short offset;
  530.  
  531.     if (maze_element_state (cur_maze, i + 1, j + 2))
  532.     {
  533.         /*
  534.          * There is a wall next to us, so make a "real" face.
  535.          */
  536.         
  537.         size = maze_size (cur_maze) - 1;
  538.         offset = size * size;
  539.  
  540.         face = make_face ();
  541.         set_face_normal (face, &world_point (cur_world, normal_offset + 3));
  542.         set_face_texture (face, wall_texture);
  543.         set_face_obstructs (face, TRUE);
  544.  
  545.         temp = i * size + j + 1;
  546.         face_points (face) = points_add_point (face_points (face),
  547.             &world_point (cur_world, temp));
  548.         face_points (face) = points_add_point (face_points (face),
  549.             &world_point (cur_world, temp + size));
  550.         face_points (face) = points_add_point (face_points (face),
  551.             &world_point (cur_world, temp + size + offset));
  552.         face_points (face) = points_add_point (face_points (face),
  553.             &world_point (cur_world, temp + offset));
  554.  
  555.         set_face_texture_o (face, &world_point (cur_world, temp));
  556.         set_face_texture_u (face, &world_point (cur_world, temp + size));
  557.         set_face_texture_v (face, &world_point (cur_world, temp + offset));
  558.  
  559.         return face;
  560.     }
  561.     else
  562.     {
  563.         /*
  564.          * There is nothing next to us, so make a "fake" face.
  565.          * (That is, it won't be visible and won't obstruct movement).
  566.          */
  567.         
  568.         face = make_face ();
  569.         set_face_normal (face, &world_point (cur_world, normal_offset + 3));
  570.         set_face_texture (face, wall_texture);
  571.         set_face_obstructs (face, FALSE);
  572.  
  573.         size = maze_size (cur_maze) - 1;
  574.         temp = i * size + j + 1;
  575.         face_points (face) = points_add_point (face_points (face),
  576.             &world_point (cur_world, temp));
  577.         face_points (face) = points_add_point (face_points (face),
  578.             &world_point (cur_world, temp + size));
  579.  
  580.         set_face_texture_o (face, &world_point (cur_world, temp));
  581.         set_face_texture_u (face, &world_point (cur_world, temp + size));
  582.         set_face_texture_v (face, &world_point (cur_world, temp + offset));
  583.  
  584.         return face;
  585.     }
  586.  
  587.     return NULL;
  588. }
  589.  
  590. /*
  591.  * Create a north face.
  592.  */
  593.  
  594. FACE
  595. world_make_north_face (i, j)
  596.     short i, j;
  597. {
  598.     FACE face;
  599.     short temp;
  600.     short size;
  601.     short offset;
  602.  
  603.     if (maze_element_state (cur_maze, i, j + 1))
  604.     {
  605.         /*
  606.          * There is a wall next to us, so make a "real" face.
  607.          */
  608.         
  609.         size = maze_size (cur_maze) - 1;
  610.         offset = size * size;
  611.  
  612.         face = make_face ();
  613.         set_face_normal (face, &world_point (cur_world, normal_offset + 4));
  614.         set_face_texture (face, wall_texture);
  615.         set_face_obstructs (face, TRUE);
  616.  
  617.         temp = i * size + j;
  618.         face_points (face) = points_add_point (face_points (face),
  619.             &world_point (cur_world, temp));
  620.         face_points (face) = points_add_point (face_points (face),
  621.             &world_point (cur_world, temp + 1));
  622.         face_points (face) = points_add_point (face_points (face),
  623.             &world_point (cur_world, temp + 1 + offset));
  624.         face_points (face) = points_add_point (face_points (face),
  625.             &world_point (cur_world, temp + offset));
  626.  
  627.         set_face_texture_o (face, &world_point (cur_world, temp));
  628.         set_face_texture_u (face, &world_point (cur_world, temp + 1));
  629.         set_face_texture_v (face, &world_point (cur_world, temp + offset));
  630.  
  631.         return face;
  632.     }
  633.     else
  634.     {
  635.         /*
  636.          * There is nothing next to us, so make a "fake" face.
  637.          * (That is, it won't be visible and won't obstruct movement).
  638.          */
  639.         
  640.         face = make_face ();
  641.         set_face_normal (face, &world_point (cur_world, normal_offset + 4));
  642.         set_face_texture (face, wall_texture);
  643.         set_face_obstructs (face, FALSE);
  644.  
  645.         size = maze_size (cur_maze) - 1;
  646.         temp = i * size + j;
  647.         face_points (face) = points_add_point (face_points (face),
  648.             &world_point (cur_world, temp));
  649.         face_points (face) = points_add_point (face_points (face),
  650.             &world_point (cur_world, temp + 1));
  651.  
  652.         set_face_texture_o (face, &world_point (cur_world, temp));
  653.         set_face_texture_u (face, &world_point (cur_world, temp + 1));
  654.         set_face_texture_v (face, &world_point (cur_world, temp + offset));
  655.  
  656.         return face;
  657.     }
  658.  
  659.     return NULL;
  660. }
  661.  
  662. /*
  663.  * Create a south face.
  664.  */
  665.  
  666. FACE
  667. world_make_south_face (i, j)
  668.     short i, j;
  669. {
  670.     FACE face;
  671.     short temp;
  672.     short size;
  673.     short offset;
  674.  
  675.     if (maze_element_state (cur_maze, i + 2, j + 1))
  676.     {
  677.         /*
  678.          * There is a wall next to us, so make a "real" face.
  679.          */
  680.         
  681.         size = maze_size (cur_maze) - 1;
  682.         offset = size * size;
  683.  
  684.         face = make_face ();
  685.         set_face_normal (face, &world_point (cur_world, normal_offset + 5));
  686.         set_face_texture (face, wall_texture);
  687.         set_face_obstructs (face, TRUE);
  688.  
  689.         temp = (i + 1) * size + j;
  690.         face_points (face) = points_add_point (face_points (face),
  691.             &world_point (cur_world, temp));
  692.         face_points (face) = points_add_point (face_points (face),
  693.             &world_point (cur_world, temp + 1));
  694.         face_points (face) = points_add_point (face_points (face),
  695.             &world_point (cur_world, temp + 1 + offset));
  696.         face_points (face) = points_add_point (face_points (face),
  697.             &world_point (cur_world, temp + offset));
  698.  
  699.         set_face_texture_o (face, &world_point (cur_world, temp + 1));
  700.         set_face_texture_u (face, &world_point (cur_world, temp));
  701.         set_face_texture_v (face, &world_point (cur_world, temp + 1 + offset));
  702.  
  703.         return face;
  704.     }
  705.     else
  706.     {
  707.         /*
  708.          * There is nothing next to us, so make a "fake" face.
  709.          * (That is, it won't be visible and won't obstruct movement).
  710.          */
  711.         
  712.         face = make_face ();
  713.         set_face_normal (face, &world_point (cur_world, normal_offset + 5));
  714.         set_face_texture (face, wall_texture);
  715.         set_face_obstructs (face, FALSE);
  716.  
  717.         size = maze_size (cur_maze) - 1;
  718.         temp = (i + 1) * size + j;
  719.         face_points (face) = points_add_point (face_points (face),
  720.             &world_point (cur_world, temp));
  721.         face_points (face) = points_add_point (face_points (face),
  722.             &world_point (cur_world, temp + 1));
  723.  
  724.         set_face_texture_o (face, &world_point (cur_world, temp + 1));
  725.         set_face_texture_u (face, &world_point (cur_world, temp));
  726.         set_face_texture_v (face, &world_point (cur_world, temp + 1 + offset));
  727.  
  728.         return face;
  729.     }
  730.  
  731.     return NULL;
  732. }
  733.